package liecai_class.day07;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.*;

/**
 * 线程池 - 提交任务
 *   execute(Runnable)
 *      最普通的提交任务的方式，没有返回值
 *   submit(Runnable)
 *      提交任务，返回Future类型的返回值，可以通过返回值判断任务是否执行完成
 *   submit(Callable)
 *      提交任务，返回Future类型的返回值，可以通过返回值判断任务是否执行完成，并获取任务的执行结果
 *   invokeAny(...)
 *      提交一批任务去执行，返回第一个执行完成的任务的执行结果，其他未完成的任务不再执行
 *   invokeAll(...)
 *      提交一批任务去执行，返回所有任务的执行结果，会等到所有任务都执行完成后，才会返回
 */
public class Demo02 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建线程池对象
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                5,
                10,
                10,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        System.out.println("###线程池过于繁忙，拒绝服务###"+r);
                    }
                }
        );

        // 提交任务 - execute(Runnable)
//        pool.execute(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("任务1...");
//            }
//        });

        // 提交任务 - submit(Runnable)
//        Future<?> future = pool.submit(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    System.out.println("任务2开始执行...");
//                    Thread.sleep(3000);
//                    System.out.println("任务2执行完成...");
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        });
//        //此方法会一直阻塞，直到其关联的任务执行完成为止
//        future.get();
//        System.out.println("Main发现任务2执行完成！");

        // 提交任务 - submit(Callable)
//        Future<String> future = pool.submit(new Callable<String>() {
//            @Override
//            public String call() throws Exception {
//                try {
//                    System.out.println("任务2开始执行...");
//                    Thread.sleep(3000);
//                    System.out.println("任务2执行完成...");
//                    return "Hellow JUC!";
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                    throw new RuntimeException(e);
//                }
//            }
//        });
//        //此方法会一直阻塞，直到其关联的任务执行完成为止,并且得到任务返回的返回值
//        String retObj = future.get();
//        System.out.println("Main发现任务2执行完成！返回值："+retObj);

        // 提交任务 - invokeAny(...)
//        Set<Callable<String>> set = new HashSet<>();
//        set.add(new Callable<String>() {
//            @Override
//            public String call() throws Exception {
//                try {
//                    System.out.println("任务1开始执行...");
//                    Thread.sleep(1000);
//                    System.out.println("任务1执行完成...");
//                    return "Hellow rw1!";
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                    throw new RuntimeException(e);
//                }
//            }
//        });
//        set.add(new Callable<String>() {
//            @Override
//            public String call() throws Exception {
//                try {
//                    System.out.println("任务2开始执行...");
//                    Thread.sleep(1000);
//                    System.out.println("任务2执行完成...");
//                    return "Hellow rw2!";
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                    throw new RuntimeException(e);
//                }
//            }
//        });
//        set.add(new Callable<String>() {
//            @Override
//            public String call() throws Exception {
//                try {
//                    System.out.println("任务3开始执行...");
//                    Thread.sleep(2000);
//                    System.out.println("任务3执行完成...");
//                    return "Hellow rw3!";
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                    throw new RuntimeException(e);
//                }
//            }
//        });
//
//        String retObj = pool.invokeAny(set);
//        System.out.println(retObj);


        // 提交任务 - invokeAll(...)
        Set<Callable<String>> set = new HashSet<>();
        set.add(new Callable<String>() {
            @Override
            public String call() throws Exception {
                try {
                    System.out.println("任务1开始执行...");
                    Thread.sleep(1000);
                    System.out.println("任务1执行完成...");
                    return "Hellow rw1!";
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        });
        set.add(new Callable<String>() {
            @Override
            public String call() throws Exception {
                try {
                    System.out.println("任务2开始执行...");
                    Thread.sleep(1000);
                    System.out.println("任务2执行完成...");
                    return "Hellow rw2!";
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        });
        set.add(new Callable<String>() {
            @Override
            public String call() throws Exception {
                try {
                    System.out.println("任务3开始执行...");
                    Thread.sleep(2000);
                    System.out.println("任务3执行完成...");
                    return "Hellow rw3!";
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        });
        List<Future<String>> list = pool.invokeAll(set);
        for (Future<String> future : list) {
            System.out.println(future.get());
        }
    }
}
